package com.macro.mall.portal.controller;

import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.service.RedisService;
import com.macro.mall.common.util.HttpClient;
import com.macro.mall.mapper.OmsOrderSettingMapper;
import com.macro.mall.mapper.UmsMemberLevelMapper;
import com.macro.mall.mapper.UmsMemberMapper;
import com.macro.mall.model.*;
import com.macro.mall.portal.dto.UmsMemberDto;
import com.macro.mall.portal.service.AboutUsService;
import com.macro.mall.portal.service.OmsPortalOrderService;
import com.macro.mall.portal.service.UmsMemberCacheService;
import com.macro.mall.portal.service.UmsMemberService;
import com.macro.mall.wx.domain.WxPayDTO;
import com.macro.mall.wx.sdk.WxMyConfig;
import com.macro.mall.wx.service.AuthService;
import com.macro.mall.wx.service.GetQrCodeService;
import com.macro.mall.wx.service.WxPayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import local.com.quyum.aliyun.aliyunsms.service.ISmsService;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 会员登录注册管理Controller
 * Created by macro on 2018/8/3.
 */
@Controller
@Api(tags = "UmsMemberController", description = "会员登录注册管理")
@RequestMapping("/sso")
public class UmsMemberController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UmsMemberController.class);
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private UmsMemberService memberService;
    @Autowired
    private ISmsService smsService;
    @Autowired
    private AboutUsService aboutUsService;
    @Autowired
    private AuthService authService;
    @Autowired
    private UmsMemberMapper umsMemberMapper;
    @Autowired
    private UmsMemberCacheService memberCacheService;
    @Autowired
    private OmsOrderSettingMapper orderSettingMapper;
    @Autowired
    private GetQrCodeService getQrCodeService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private OmsPortalOrderService portalOrderService;
    @Autowired
    private UmsMemberLevelMapper levelMapper;
    @Autowired
    private RedisService redisService;

    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

    @ApiOperation("会员注册")
    @RequestMapping(value = "/register/{authCode}", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult register(@RequestParam String realName,
                                 @RequestParam String password,
                                 @RequestParam String phone,
                                 @RequestParam String authCode,
                                 @RequestParam(required = false) Long agentId) {
        String register = memberService.register(realName, password, phone, authCode, agentId);
        if(StringUtils.isBlank(register)){
            return CommonResult.success(null, "注册成功");
        }else {
            return CommonResult.failed(register);
        }
    }

    /**
     * 获取微信登录openId
     * @author zhouboyu
     * @Date 2020年9月10日
     *
     * @param memberId
     * @param jsCode
     * @return
     */
    @ApiOperation("获取微信登录openId")
    @RequestMapping(value = "/getOpenId", method = RequestMethod.POST ,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult<String> register(@RequestParam("memberId") Long memberId,@RequestParam("jsCode") String jsCode) {
        CommonResult<String> result ;
        UmsMember umsMember = memberService.getById(memberId);
        if(umsMember!=null){
            String openId = this.authService.getOpenId(jsCode);
            if(StringUtils.isNotBlank(openId)){
                UmsMemberExample example = new UmsMemberExample();
                example.createCriteria().andOpenIdEqualTo(openId);
                List<UmsMember> memberList = umsMemberMapper.selectByExample(example);
                int i = 1;
                if (CollectionUtils.isEmpty(memberList)) {
                    umsMember.setOpenId(openId);
                    i = this.umsMemberMapper.updateByPrimaryKey(umsMember);
                    this.memberCacheService.delMember(memberId);
                }
                if(i>0){
                    result = CommonResult.success(openId, "获取成功");
                }else{
                    result = CommonResult.failed();
                }
            }else{
                result = CommonResult.failed();
            }
            return result;
        }
        return CommonResult.failed();
    }

    @ApiOperation("获取微信登录openId")
    @RequestMapping(value = "/getOpenIdByCode", method = RequestMethod.POST ,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult<String> getOpenId(@RequestParam("jsCode") String jsCode) {
        String openId = this.authService.getOpenId(jsCode);
        if (openId != null && !"".equals(openId)) {
            return CommonResult.success(openId);
        }else {
            return CommonResult.failed();
        }
    }

    @ApiOperation("会员登录")
    @RequestMapping(value = "/login",method = RequestMethod.POST ,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult login(@RequestParam String username,
                              @RequestParam String password,
                              @RequestParam Integer type,
                              @RequestParam(required = false) Long agentId) {
        String token = null;
        Map<String, String> login = null;
        try{
            login = memberService.login(username, password, type, agentId);
        }  catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
            return CommonResult.validateFailed(e.getMessage());
        }
        if (login == null || login.get("token") == null) {
            return CommonResult.validateFailed("用户名或密码错误");
        }
        return CommonResult.success(login);
    }

    @ApiOperation("会员登录")
    @RequestMapping(value = "/loginByOpenId",method = RequestMethod.POST ,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult login(@RequestParam String openId) {
        String token = null;
        Map<String, String> login = null;
        try{
            login = memberService.loginByOpenId(openId);
        }  catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
            return CommonResult.validateFailed(e.getMessage());
        }
        if (login == null || login.get("token") == null) {
            return CommonResult.validateFailed("首次登录需要账号密码登录");
        }
        return CommonResult.success(login);
    }

    @ApiOperation("获取会员信息")
    @RequestMapping(value = "/info", method = RequestMethod.GET ,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult info(Principal principal) {
        if (principal == null) {
            return CommonResult.unauthorized(null);
        }
        UmsMember member = memberService.getCurrentMember();
        return CommonResult.success(member);
    }

//    @ApiOperation("获取验证码")
//    @RequestMapping(value = "/getAuthCode", method = RequestMethod.GET)
//    @ResponseBody
//    public CommonResult getAuthCode(@RequestParam String telephone) {
//        String authCode = memberService.generateAuthCode(telephone);
//        return CommonResult.success(authCode, "获取验证码成功");
//    }

    /**
     * 修改密码
     * 先进行验证码校验，成功了之后再修改密码
     * 之前是验证码和密码一起输入的
     * @param telephone
     * @param password
     * @return
     * @author 高强
     * @Date 2020年8月29日
     */
    @ApiOperation("修改密码")
    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult updatePassword(@RequestParam String telephone,
                                       @RequestParam String password) {
        memberService.updatePassword(telephone, password);
        return CommonResult.success(null, "密码修改成功");
    }


    @ApiOperation(value = "刷新token")
    @RequestMapping(value = "/refreshToken", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult refreshToken(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        String refreshToken = memberService.refreshToken(token);
        if (refreshToken == null) {
            return CommonResult.failed("token已经过期！");
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", refreshToken);
        tokenMap.put("tokenHead", tokenHead);
        return CommonResult.success(tokenMap);
    }


    /**
     * 前台点击获取验证码，调用该接口，返回发送成功或发送失败
     *
     * @param mobile 手机号
     * @return
     */
    @ApiOperation(value = "点击获取验证码")
    @RequestMapping(value = "/sendAuthCode", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult sendAuthCode(@RequestParam(value = "mobile") String mobile,@RequestParam(defaultValue = "0" ,required = false) Integer type) {
        return memberService.sendAuthCode(mobile,type);
    }

    /**
     * 校验验证码
     * 忘记密码并且获取验证码之后,调用该接口，返回true，验证码校验成功，跳转到修改密码界面
     *
     * @param mobile   手机号
     * @param authCode 验证码
     * @return
     */
    @ApiOperation(value = "校验验证码")
    @RequestMapping(value = "/verifyAuthCode", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult verifyAuthCode(@RequestParam String mobile, @RequestParam String authCode) {
        if (StringUtils.isEmpty(authCode)) {
            return CommonResult.failed("验证码为空");
        }
        return smsService.verifyCode(mobile, authCode);

    }

    /**
     * 用户开通会员
     * @param memberLevelId 会员等级id：1非会员、2包月会员、3季度会员、4半年会员、5年度会员
     * @return
     */
    @ApiOperation(value = "开通会员")
    @RequestMapping(value = "/openMemberLevel", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult openMemberLevel(HttpServletRequest request,@RequestParam Long memberLevelId,@RequestParam(required = false,defaultValue = "1") Integer type) {
        UmsMember member = this.memberService.getCurrentMember();
        String sn = sdf.format(new Date())+"-"+memberLevelId+"-"+member.getId();
        String ipAddress = HttpClient.getIpAddress(request);
        try {
            WxMyConfig.TRADE_TYPE trade_type = WxMyConfig.TRADE_TYPE.JSAPI;
            if (type.equals(0)) {
                trade_type = WxMyConfig.TRADE_TYPE.MWEB;
            }
            WxPayDTO wxPayDTO = new WxPayDTO(trade_type);
            wxPayDTO.setBody("美壤会员");
            // openId
            wxPayDTO.setOpenid(member.getOpenId());
            // 订单号,每次都不同
            wxPayDTO.setOut_trade_no(sn);
            wxPayDTO.setSpbill_create_ip(ipAddress);
            // 支付类型
            UmsMemberLevel umsMemberLevel = levelMapper.selectByPrimaryKey(memberLevelId);
            BigDecimal bigDecimal = umsMemberLevel.getPrice().multiply(BigDecimal.TEN.multiply(BigDecimal.TEN)).setScale(0);
            String fee = "1";
            if(bigDecimal.compareTo(BigDecimal.ZERO)>0){
                fee  = bigDecimal.toString();
            }
            wxPayDTO.setTotal_fee(fee);
//            wxPayDTO.setTotal_fee("1");
            Map<String, String> map = this.wxPayService.wxPay(wxPayDTO);
            if(!CollectionUtils.isEmpty(map)){
                member.setMemberOrderSn(sn);
                umsMemberMapper.updateByPrimaryKeySelective(member);
                return CommonResult.success(map);
            }else {
                return CommonResult.failed("支付失败，请稍后再试");
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.failed("支付失败，请稍后再试");
    }



    /**
     * 修改手机号校验密码
     * author 孙晓亮
     * Date 2020年9月11日
     * @param password 密码
     * @return
     */
    @ApiOperation(value = "校验密码")
    @RequestMapping(value = "/verifyPassword", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult verifyPassword(@RequestParam String password){
        if (StringUtils.isEmpty(password)) {
            return CommonResult.failed("密码为空");
        }
        return memberService.verifyPassword( password);

    }

    /**
     * 修改手机号
     * author 孙晓亮
     * Date 2020年9月11日
     * @param authCode 验证码
     * @param phone 手机号
     * @return
     */
    @ApiOperation(value = "修改手机号")
    @RequestMapping(value = "/updateMemberPhone", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult updateMemberPhone(@RequestParam String authCode, @RequestParam String phone){
        if (StringUtils.isEmpty(authCode)) {
            return CommonResult.failed("验证码不能为空");
        }
        if(StringUtils.isEmpty(phone)){
            return CommonResult.failed("手机号不能为空");
        }
        return memberService.updateMemberPhone(authCode,phone);
    }

    /**
     * 获取当前用户及绑定门店
     * @return
     */
    @ApiOperation(value = "获取当前用户及绑定门店")
    @RequestMapping(value = "/getMemberStore", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<HashMap> getMemberStore(){
        return memberService.getMemberStore();
    }
    /**
     * 绑定门店
     * 
     * @author zhouboyu
     * @Date 2020年9月11日
     * @param lat
     *          纬度
     * @param lon
     *          经度
     * @return
     */
    @ApiOperation(value = "绑定门店")
    @RequestMapping(value = "/bindStore", method = RequestMethod.POST ,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult<UmsStore> bindStore(@RequestParam Double lat, @RequestParam Double lon){
        return this.memberService.bindStore(lat,lon);
    }

    /**
     * 修改部分用户信息
     * @author 高强
     * @Date 2020年9月2日
     * @param umsMemberDto 修改的参数
     * @return
     */
    @ApiOperation(value = "修改部分用户信息")
    @RequestMapping(value = "/updateMemberInfo", method = RequestMethod.POST ,consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public CommonResult<UmsMemberDto> updateMemberInfo(@RequestBody UmsMemberDto umsMemberDto){
        return memberService.updateMemberInfo(umsMemberDto);
    }

    /**
     * 用户签到功能
     * @return
     */
    @ApiOperation(value = "用户签到功能")
    @RequestMapping(value = "/checkIn", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult checkIn(){
        return memberService.checkIn();
    }

    /**
     * 查看当前用户签到情况
     * @return 用户的签到状态和绑定门店的签到积分设置的封装
     */
    @ApiOperation(value = "查看当前用户签到情况")
    @RequestMapping(value = "/getCheckIn", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<HashMap> getCheckIn(){
        return memberService.getCheckIn();
    }


    /**
     * 获取关于我们
     * @return
     */
    @ApiOperation(value = "获取关于我们")
    @RequestMapping(value = "/getAboutUs", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<UmsAboutUs> getAboutUs(){
        return aboutUsService.getAboutUs();
    }

    /**
     * 用户进行意见反馈
     * @param feedback
     * @return
     */
    @ApiOperation(value = "用户进行意见反馈")
    @RequestMapping(value = "/feedback", method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public CommonResult createFeedback(@RequestBody UmsFeedback feedback){
        return aboutUsService.createFeedback(feedback);
    }

    /**
     * 获取会员页面
     * @param type 1是用钱买的，0是用积分换的
     * @return
     */
    @RequestMapping(value = "/getMemberInfo", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<UmsMemberLevel>> getMemberInfo(@RequestParam Integer type){
        return memberService.getMemberInfo(type);
    }

    /**
     * 获取积分记录
     * @return
     */
    @RequestMapping(value = "/getIntegrationList", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<UmsIntegrationChangeHistory>> getIntegrationList(){
        List<UmsIntegrationChangeHistory> integrationList = memberService.getIntegrationList();
        return CommonResult.success(integrationList);
    }

    /**
     * 使用积分开通会员更改用户积分
     * @param memberLevelId
     * @return
     */
    @RequestMapping(value = "/setMemberLevelByIntegration", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult setMemberLevelByIntegration(@RequestParam Long memberLevelId){
        return memberService.setMemberLevelByIntegration(memberLevelId);
    }
    /**
     * 获取当前用户订单数量
     * @author zhouboyu
     * @Date 2020年9月23日
     * @param type
     *          0普通用户1经纪人
     * @return
     */
    @RequestMapping(value = "/getOrderCounts", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<Map<String, Object>> getOrderCounts(@RequestParam Integer type){
        return this.memberService.getOrderCounts(type);
    }
    /**
     * 获取二维码
     * @param page
     * @return
     * @author zhouboyu
     * @Date 2020年9月13日
     */
    @GetMapping(value = "/getQrCode")
    @ResponseBody
    public CommonResult<String> getQrCode(String page) {
        UmsMember currentMember = this.memberService.getCurrentMember();
        OmsOrderSetting omsOrderSetting = this.orderSettingMapper.selectByPrimaryKey(1L);
        byte[] qrCode = this.getQrCodeService.getQrCode(currentMember.getId().toString(), page, omsOrderSetting.getAccessToken());
        return CommonResult.success((new sun.misc.BASE64Encoder()).encode(qrCode));
    }

    /**
     * 经纪人上传定位
     * @author 高强
     * @Date 2020年9月29日
     * @param memberId
     * @param lat
     * @param lon
     * @return
     */
    @RequestMapping(value = "/uploadPosition", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult uploadPosition(@RequestParam Long memberId,@RequestParam Double lat,@RequestParam Double lon){
        return this.memberService.uploadPositioning(memberId,lat,lon);
    }
}
